package com.yilin.tms.order.controller;

import com.google.gson.reflect.TypeToken;
import com.yilin.commons.exception.BusinessException;
import com.yilin.commons.util.ArrayUtil;
import com.yilin.commons.util.JsonUtil;
import com.yilin.commons.util.StringUtil;
import com.yilin.tms.core.application.PageData;
import com.yilin.tms.core.application.ReturnData;
import com.yilin.tms.core.commons.base.BaseController;
import com.yilin.tms.core.commons.model.AuthData;
import com.yilin.tms.core.commons.annotation.Explain;
import com.yilin.tms.core.commons.annotation.NotNull;
import com.yilin.tms.core.commons.annotation.SkipLoginVerify;
import com.yilin.tms.core.commons.annotation.UserTarget;
import com.yilin.tms.core.commons.utils.ParamUtil;
import com.yilin.tms.core.entity.order.goods.GoodsOrder;
import com.yilin.tms.core.entity.order.payment.OrderPaymentCost;
import com.yilin.tms.core.entity.order.rob.RobOrder;
import com.yilin.tms.core.entity.user.OrganType;
import com.yilin.tms.core.entity.user.account.Account;
import com.yilin.tms.core.entity.user.RoleType;
import com.yilin.tms.core.entity.user.UserType;
import com.yilin.tms.core.entity.user.organize.MemberType;
import com.yilin.tms.core.entity.user.organize.Organize;
import com.yilin.tms.order.service.order.IGoodsService;
import com.yilin.tms.order.service.order.IRobService;
import com.yilin.tms.order.service.owner.IGoodsOwnerService;
import com.yilin.tms.order.service.owner.IRobOwnerService;
import com.yilin.tms.order.service.payment.IOrderPaymentCostService;
import com.yilin.tms.core.remote.IUserRemote;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;

/**
 * 抢单控制器
 *
 * @author zhangjinyuan
 * @date 2022/10/30
 */
@RestController
@RequestMapping("/order/rob/")
public class RobController extends BaseController {

    @Resource
    IGoodsService goodsService;
    @Resource
    IRobService robService;
    @Resource
    IRobOwnerService robOwnerService;
    @Resource
    IGoodsOwnerService goodsOwnerService;
    @Resource
    IOrderPaymentCostService orderPaymentCostService;

    @Resource
    IUserRemote userRemote;

    /**
     * 获取抢单分页
     */
    @PostMapping(value = "getRobOrderPage")
    @NotNull({"page", "limit"})
    public ReturnData<PageData<RobOrder>> getRobOrderPage(RobOrder query, @Explain("页码") Integer page, @Explain("条数") Integer limit) {
        PageData<RobOrder> pageData = robService.getRobOrderPage(getLoginUser(), query, page, limit);
        return jsonView(true, "获取抢单列表成功", pageData);
    }

    /**
     * 获取抢单详情
     */
    @PostMapping(value = "getRobOrderDetail")
    @NotNull("robOrderId")
    public ReturnData<RobOrder> getRobOrderDetail(@Explain("抢单ID") String robOrderId) {
        RobOrder robOrder = robService.getRobOrderDetail(getLoginUser(), robOrderId);
        return jsonView(SUCCESS_CODE, "获取抢单详情成功", robOrder);
    }

    /**
     * 根据ID查询抢单
     */
    @PostMapping(value = "getRobOrderById")
    @NotNull("robOrderId")
    public ReturnData<RobOrder> getRobOrderById(@Explain("抢单ID") String robOrderId) {
        RobOrder robOrder = robService.getById(robOrderId);
        return jsonView(true, "获取抢单详情成功", robOrder);
    }

    /**
     * 获取抢单分页 隐藏敏感信息
     */
    @PostMapping(value = "getPublicRobOrderPage")
    @NotNull({"page", "limit"})
    @SkipLoginVerify
    public ReturnData<PageData<RobOrder>> getPublicRobOrderPage(RobOrder query, @Explain("页码") Integer page, @Explain("条数") Integer limit) {
        PageData<RobOrder> pageData = robService.getPublicRobOrderPage(query, page, limit);
        return jsonView(SUCCESS_CODE, "获取抢单列表成功", pageData);
    }

    /**
     * 货主分配抢单
     */
    @PostMapping(value = "assignRobOrder")
    @NotNull({"goodsOrderId", "robOrderListJson"})
    @UserTarget(UserType.shipperUser)
    public ReturnData<Object> assignRobOrder(@Explain("货单ID") String goodsOrderId, @Explain("抢单List") String robOrderListJson) {
        List<RobOrder> formRobOrderList = JsonUtil.jsonToObject(robOrderListJson, new TypeToken<List<RobOrder>>() {});
        if (formRobOrderList == null) throw new BusinessException("分配抢单解析失败!");
        GoodsOrder localGoodsOrder = goodsService.getById(goodsOrderId);
        ParamUtil.isNull(localGoodsOrder, "未找到原始货源");
        ParamUtil.notEquals("只能分配保存状态下的货源", localGoodsOrder.getGoodsStatus(), GoodsOrder.GoodsStatus.save);
        if (localGoodsOrder.getFullLoad() && formRobOrderList.size() > 1) {
            throw new BusinessException("整车货源不能分配多个抢单!");
        }
        if (localGoodsOrder.getEndTime() != null && localGoodsOrder.getEndTime().getTime() < System.currentTimeMillis()) {
            throw new BusinessException("该货源已过期，请刷新货源重新发布!");
        }
        for (RobOrder robOrder : formRobOrderList) {
            if (robOrder.getRobType() == null) robOrder.setRobType(RobOrder.RobType.assign);
            ParamUtil.isNull(robOrder.getRobOrderNoteList(), "分配抢单资源量为空！");
            ParamUtil.isNull(robOrder.getRobOrganizeId(), "未知的车主");
            Organize robOrganize = ParamUtil.isSuccess(userRemote.getOrganizeById(robOrder.getRobOrganizeId()));
            robOrder.setRobAccountId(robOrganize.getManagerUserId());
            //检查车主认证信息
            List<AuthData.AuthItem> itemList = ArrayUtil.initList(AuthData.AuthItem.authIdCard);
            if (robOrganize.getOrganType() != OrganType.individual) itemList.addAll(ArrayUtil.initList(AuthData.AuthItem.authBusinessLicense,AuthData.AuthItem.authTransBusinessLicense));
            ParamUtil.isSuccess(userRemote.checkAuthStatus(robOrganize.getManagerUserId(), itemList.toArray(new AuthData.AuthItem[0])));
            //检查车主车型条件
            ReturnData<String> returnData = goodsOwnerService.robVehicleTypeMatching(robOrder.getRobOrganizeId(), localGoodsOrder);
            if (!returnData.isSuccess()) return jsonErrView(String.format("车主:%s 下拥有车型不满足货源要求，无法分配", robOrder.getRobOrganizeName()));
        }
        robService.batchAssignGoodsOder(getLoginUser(), localGoodsOrder, formRobOrderList);
        return jsonView(SUCCESS_CODE, "分配抢单成功");
    }

    /**
     * 车主申请抢单
     */
    @PostMapping(value = "saveRobOrder")
    @NotNull({"goodsOrderId", "robNoteDetailList"})
    @UserTarget(UserType.truckerUser)
    public ReturnData<Object> saveRobOrder(RobOrder robOrder) {
        ParamUtil.notEquals("仅限管理员操作", getLoginUser().getRoleType(), RoleType.manager);
        //检查收发货节点数量
        robOwnerService.checkReceiveAndDeliverNote(robOrder);
        GoodsOrder localGoodsOrder = goodsService.getById(robOrder.getGoodsOrderId());
        ParamUtil.isNull(localGoodsOrder, "未找到货源");
        ParamUtil.notEquals("该货源已下线", localGoodsOrder.getGoodsStatus(), GoodsOrder.GoodsStatus.release);
        if (localGoodsOrder.getEndTime() != null && localGoodsOrder.getEndTime().getTime() < System.currentTimeMillis()) {
            Organize organize = ParamUtil.isSuccess(userRemote.getOrganizeById(getLoginUser().getSuperiorPlatId()));
            Account platformAccount = ParamUtil.isSuccess(userRemote.getAccountById(organize.getManagerUserId()));
            goodsService.recallGoodsOrder(platformAccount, localGoodsOrder);
            return jsonView(false, "该货源已过期！");
        }
        List<RobOrder> robOrderList = robService.getWaitRobByGoodsOrderId(getLoginUser().getId(), robOrder.getGoodsOrderId());
        if (robOrderList.size() > 0) throw new BusinessException("该货源您已经存在审核中的抢单，请先等待审核结果");
        ReturnData<String> returnData = goodsOwnerService.robVehicleTypeMatching(getLoginUser().getOrganizeId(), localGoodsOrder);
        if (!returnData.isSuccess()) return jsonView(false, returnData.getMsg());
        //检查车主基本信息认证是否完善
        List<AuthData.AuthItem> itemList = ArrayUtil.initList(AuthData.AuthItem.authIdCard);
        if (getLoginUser().getOrganType() != OrganType.individual) {
            itemList.addAll(ArrayUtil.initList(AuthData.AuthItem.authBusinessLicense,AuthData.AuthItem.authTransBusinessLicense));
        }
        ParamUtil.isSuccess(userRemote.checkAuthStatus(getLoginUser().getId(), itemList.toArray(new AuthData.AuthItem[0])));
        robOrder = robService.saveRobOrder(getLoginUser(), robOrder);
        return jsonView(SUCCESS_CODE, "申请抢单成功", robOrder.getId());
    }

    /**
     * 货主审核抢单
     */
    @PostMapping(value = "auditRobOrder")
    @NotNull({"id", "robStatus"})
    @UserTarget(UserType.shipperUser)
    public ReturnData<Object> auditRobOrder(String id, RobOrder.RobStatus robStatus, String auditBackReason) {
        ParamUtil.notEquals("审核结果无效", robStatus, RobOrder.RobStatus.success, RobOrder.RobStatus.back);
        if (robStatus == RobOrder.RobStatus.back && StringUtil.isEmpty(auditBackReason)) {
            return jsonView(false, "请说明退回原因");
        }
        RobOrder localRobOrder = robService.getById(id);
        GoodsOrder localGoodsOrder = goodsService.getById(localRobOrder.getGoodsOrderId());
        ParamUtil.notEquals("您无权操作", localGoodsOrder.getShipperAccountId(), getLoginUser().getId());
        ParamUtil.notEquals("车主已撤单或审核已完成，无需审核", localRobOrder.getRobStatus(), RobOrder.RobStatus.wait);
        //robOrder->localRobOrder
        localRobOrder.setRobStatus(robStatus);
        localRobOrder.setAuditBackReason(auditBackReason);
        robService.auditRobOrder(getLoginUser(), localGoodsOrder, localRobOrder);
        return jsonView(SUCCESS_CODE, "审核抢单成功");
    }

    /**
     * 货主批量审核抢单
     */
    @PostMapping(value = "batchAuditRobOrder")
    @NotNull("robOrderIds")
    @UserTarget(UserType.shipperUser)
    public ReturnData<Object> batchAuditRobOrder(String[] robOrderIds) {
        int success = 0;
        for (String robId : robOrderIds) {
            RobOrder localRobOrder = robService.getById(robId);
            GoodsOrder localGoodsOrder = goodsService.getById(localRobOrder.getGoodsOrderId());
            if (!localGoodsOrder.getShipperAccountId().equals(getLoginUser().getId())) break;
            if (localRobOrder.getRobStatus() != RobOrder.RobStatus.wait) break;
            localRobOrder.setRobStatus(RobOrder.RobStatus.success);
            robService.auditRobOrder(getLoginUser(), localGoodsOrder, localRobOrder);
            success++;
        }
        return jsonView(true, "审核成功：" + success + "条，失败：" + (robOrderIds.length - success) + "条");
    }

    /**
     * 车主分配车辆 生成运单
     */
    @PostMapping(value = "assignTruck")
    @NotNull({"id", "robOrderNoteList"})
    @UserTarget(UserType.truckerUser)
    public ReturnData<Object> assignTruck(RobOrder robOrder) {
        RobOrder localRobOrder = robService.getById(robOrder.getId());
        ParamUtil.isNull(localRobOrder, "没有找到抢单信息");
        ParamUtil.isNull(localRobOrder.getRobAccountId(), "抢单车主ID为空");
        ParamUtil.equals("抢单已在运输中", localRobOrder.getRobStatus(), RobOrder.RobStatus.confirmed);
        ParamUtil.notEquals("此抢单未审核或审核未成功", localRobOrder.getRobStatus(), RobOrder.RobStatus.success);
        ParamUtil.notEquals("您无权操作", localRobOrder.getRobAccountId(), getLoginUser().getId());
        GoodsOrder localGoodsOrder = goodsService.getById(localRobOrder.getGoodsOrderId());
        ParamUtil.isNull(localRobOrder, "没有找到货单信息");
        //检查支付状态
        OrderPaymentCost paymentCost = orderPaymentCostService.getOrderPaymentByRobOrderId(localRobOrder.getId());
        List<OrderPaymentCost.PayStatus> payStatuses = ArrayUtil.initList(OrderPaymentCost.PayStatus.none, OrderPaymentCost.PayStatus.complete);
        if (!payStatuses.contains(paymentCost.getPayStatus())) return jsonErrView("请先等待货主支付抢单运费，运输完成前，运费交由平台托管！");
        //检查车主基本信息认证是否完善
        List<AuthData.AuthItem> itemList = ArrayUtil.initList(AuthData.AuthItem.authIdCard);
        if (getLoginUser().getOrganType() != OrganType.individual) {
            itemList.add(AuthData.AuthItem.authBusinessLicense);
            itemList.add(AuthData.AuthItem.authTransBusinessLicense);
        }
        ParamUtil.isSuccess(userRemote.checkAuthStatus(getLoginUser().getId(), itemList.toArray(new AuthData.AuthItem[0])));
        //robOrder->localRobOrder
        localRobOrder.setRobOrderNoteList(robOrder.getRobOrderNoteList());
        String myTransitOrderId = robService.assignTruck(getLoginUser(), localRobOrder, localGoodsOrder);
        return jsonView(SUCCESS_CODE, "分配车辆 成功", myTransitOrderId);
    }

    /**
     * 车主撤销抢单
     */
    @PostMapping(value = "cancelRobOrder")
    @NotNull({"id"})
    @UserTarget(UserType.truckerUser)
    public ReturnData<Object> cancelRobOrder(RobOrder robOrder) {
        RobOrder localRobOrder = robService.getById(robOrder.getId());
        ParamUtil.isNull(localRobOrder, "未知的抢单");
        ParamUtil.notEquals("您无权操作", localRobOrder.getRobAccountId(), getLoginUser().getId());
        ParamUtil.notEquals("该抢单状态不能取消", localRobOrder.getRobStatus(), RobOrder.RobStatus.success, RobOrder.RobStatus.wait);
        int number = robService.getCancelNumberByUser(getLoginUser());
        MemberType memberType = ParamUtil.isSuccess(userRemote.getMyMemberTypeByOrganizeId(getLoginUser().getOrganizeId()));
        if (robOrder.getRobType() == RobOrder.RobType.robing && number >= memberType.getCancelRobCount()) {
            return jsonView(false, "您今日取消主抢单次数过多，请联系平台取消！");
        }
        robService.cancelRobOrder(getLoginUser(), localRobOrder);
        return jsonView(SUCCESS_CODE, "抢单取消成功");
    }

    /**
     * 平台操作销单
     */
    @PostMapping(value = "deleteRobOrders")
    @NotNull({"robOrderIds"})
    @UserTarget(UserType.platformUser)
    public ReturnData<Object> deleteRobOrders(@Explain("抢单ID数组") String[] robOrderIds) {
        int success = 0;
        List<RobOrder> robOrderList = robService.listByIds(Arrays.asList(robOrderIds));
        for (RobOrder robOrder : robOrderList) {
//            ParamUtil.notEquals("该抢单不属于您的平台，无权操作", getLoginUser().getOrganizeId(), null);
            if (robOrder.getRobStatus() != RobOrder.RobStatus.wait && robOrder.getRobStatus() != RobOrder.RobStatus.success) {
                continue;
            }
            robService.cancelRobOrder(getLoginUser(), robOrder);
            success++;
        }
        return jsonView(true, "销单成功：" + success + "条");
    }


//
//
//    /**
//     * 获取抢单统计数据
//     */
//    @PostMapping("getRobStatistics")
//    public ReturnData<RobStatistics> getRobStatistics() {
//        ParamUtil.equals("无权访问", getLoginUser().getUserType(), UserType.shipperUser,
//                UserType.truckerUser);
//        RobStatistics robStatistics = robService.getRobStatistics(loginUser);
//        return jsonView(true, "获取成功", robStatistics);
//    }

}
